#pragma once

#include <list>

#define AUTOLOCK
#define UNLOCK_WAITFORTIMEOUT_LOCK
#define NOTIFY

template <typename T>
class SyncQueue {
public:
    SyncQueue()
    : mWaits(0) {
    }

    virtual ~SyncQueue() {
    }

    int Enqueue(const T& obj) {
        AUTOLOCK;
        mList.push_back(obj);
        if (mWaits > 0) {
            NOTIFY;
        }
        return mList.size();
    }

    bool Dequeue(T& obj) {
        AUTOLOCK;
        if (mList.empty()) {
            ++mWaits;
            UNLOCK_WAITFORTIMEOUT_LOCK;
            --mWaits;
        }
        if (mList.empty()) {
            return false;
        }
        obj = mList.front();
        mList.pop_front();
        return true;
    }

protected:
    std::list<T> mList;
    int mWaits;
};
